#!/usr/bin/env python
# -*- coding: utf-8 -*-
#

import  time
import  traceback

from os.path import basename

class   LogRecord(object) :
    '''
    Log record
    '''
    def    __init__(self, level, msg, filename=None, lineno=0) :
        self.ctime = time.time()
        self.level = level
        self.msg = msg
        self.filename = filename
        self.lineno = lineno
        
    # class LogRecord
    
class   LogAppender(object) :
    '''
    Log Appender
    '''
    def    append(self, record) :
        when = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(record.ctime))
        if record.filename :
            print "%s %s:%d [%s] %s" % (when, record.filename, record.lineno, record.level, record.msg)
        else :
            print "%s [%s] %s" % (when, record.level, record.msg)
        
    # class LogAppender
    
LOG_LEVEL_NONE  = 9999
LOG_LEVEL_ERROR = 9000
LOG_LEVEL_WARN  = 8000
LOG_LEVEL_INFO  = 7000
LOG_LEVEL_DEBUG = 5000
LOG_LEVEL_ALL   = 0

    
class	Logger(object) :
    '''
    Logger
    '''
    LEVEL_ERROR = 'ERROR'
    LEVEL_WARN  = 'WARN'
    LEVEL_INFO  = 'INFO'
    LEVEL_DEBUG = 'DEBUG'
    
    def     __init__(self) :
        self.__appender = LogAppender()
        self.__loglevel = LOG_LEVEL_INFO        # default log-level
    
    def     error(self, msg) :
        if LOG_LEVEL_ERROR < self.__loglevel : return
        filename, lineno, module, function = self.__tracestack()
        record = LogRecord(level=self.LEVEL_ERROR, msg=msg, filename=filename, lineno=lineno)
        self.__log(record)
        
    def     warn(self, msg) :
        if LOG_LEVEL_WARN < self.__loglevel : return
        filename, lineno, module, function = self.__tracestack()
        record = LogRecord(level=self.LEVEL_WARN, msg=msg, filename=filename, lineno=lineno)
        self.__log(record)
        
    def     info(self, msg) :
        if LOG_LEVEL_INFO < self.__loglevel : return
        filename, lineno, module, function = self.__tracestack()
        record = LogRecord(level=self.LEVEL_INFO, msg=msg, filename=filename, lineno=lineno)
        self.__log(record)
        
    def     debug(self, msg) :
        if LOG_LEVEL_DEBUG < self.__loglevel : return
        filename, lineno, module, function = self.__tracestack()
        record = LogRecord(level=self.LEVEL_DEBUG, msg=msg, filename=filename, lineno=lineno)
        self.__log(record)
        
    def     __log(self, record) :
        self.__appender.append(record)
        
    def     __tracestack(self) :
        stack = traceback.extract_stack()
        LAYER = -3
        filename = basename(stack[LAYER][0])
        lineno   = stack[LAYER][1]
        module   = stack[LAYER][2]
        function = stack[LAYER][3]
        return  (filename, lineno, module, function)
        
    def     setLogLevel(self, log_level) :
        assert (LOG_LEVEL_ALL <= log_level) and (log_level <= LOG_LEVEL_NONE)
        self.__loglevel = log_level
        
    # class Logger
    
rootLogger = Logger()
    
def    getLogger() :
    return    rootLogger
            
    